﻿using ChongJu.CameraCalibration.Calibration;
using ChongJu.ImageAnalyze;
using ChongJu.ModelManager.Calibration;
using Public.Logger;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace ChongJu.CameraCalibration
{
    public class CalibrationService
    {
        private CalibrationClient _client;


        public CalibrationService()
        {
            _client = new CalibrationClient();
            //_client.Create();
        }


        public bool Init(CalibrationCfgModel data)
        {
            try
            {
                var bol = _client.SetAdjustmentTarget(data.StandR, data.StandG, data.StandB);
                if(bol == false)
                {
                    Logger.Error("_client.SetAdjustmentTarget 失败");
                    return false;
                }

                bol = _client.SetAdjustmentFactor(data.RateR, data.RateG, data.RateB);
                if(bol == false)
                {
                    Logger.Error("_client.SetAdjustmentFactor 失败");
                    return false;
                }

                return true;
            }
            catch(Exception ex)
            {
                Logger.Error("初始化相机校准异常：", ex);
                return false;
            }
        }


        public Task<string> GetRGB(CalibrationModel model)
        {
            return Task.Factory.StartNew(() =>
            {
                try
                {
                    if (string.IsNullOrEmpty(model.ImageDir) == true)
                        return "灰板路径为空";

                    var files = new DirectoryInfo(model.ImageDir).GetFiles().ToList();
                    if (files.Count == 0)
                        return "没有图片";

                    double r_std = 0;
                    double g_std = 0;
                    double b_std = 0;
                    files.ForEach(f =>
                    {
                        var image = Marshal.StringToHGlobalAnsi(f.FullName);
                        ImageRGBModel info = new ImageRGBModel();
                        var bol = _client.GetImageRGB(image, model.X, model.Y, model.W, model.H,
                                                ref info.R,
                                                ref info.G,
                                                ref info.B,
                                                ref r_std,
                                                ref g_std,
                                                ref b_std);
                        info.Name = f.Name;
                        model.LstImage.Add(info);
                    });
                    return null;
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            });
        }

        public Task<string> Run(CalibrationSDKModel model, bool _isLight = true)
        {
            return Task.Factory.StartNew(() =>
            {
                try
                {
                    //获取rgb值
                    var dir = Marshal.StringToHGlobalAnsi(model.ImageDir);

                    double r_g = 0;
                    double g_g = 0;
                    double b_g = 0;
                    int r_m = 0;
                    int g_m = 0;
                    int b_m = 0;
                    int light = 0;
                    int success = 0;
                    AnalyzeService.Instance.CalibraLightCamera(dir, 
                        (int)model.StandB, (int)model.StandG, (int)model.StandR, 
                        ref b_g, ref g_g, ref r_g,
                        ref light, ref b_m, ref g_m, ref r_m, 
                        ref success);

                    model.TestR = Math.Round(r_g, 2);
                    model.TestG = Math.Round(g_g, 2);
                    model.TestB = Math.Round(b_g, 2);
                    model.Expose = model.Expose + light;
                    model.OutDelay = model.OutDelay + light;
                    model.SubValue = light;

                    model.MultiplyR = r_m;
                    model.MultiplyG = g_m;
                    model.MultiplyB = b_m;

                    if (success < 2)
                        model.Type = CalibrationEnum.Light;
                    else if (success >= 2 & success < 5)
                        model.Type = CalibrationEnum.Minutely;

                    model.IsComplete = success >= 5;

                    #region
                    //int flag = -1;
                    //if(_isLight == true)
                    //{
                    //    double voltage = -1;
                    //    //光源调整接口，flag返回值为 0：（失败）继续调用 2：成功
                    //    bol = _client.Get_brightness_propose(model.TestR, model.TestG, model.TestB, ref voltage, ref flag);
                    //    model.MultiplyLuminance = (int)voltage;
                    //}
                    //else
                    //{
                    //    int r_mean_result = -1;
                    //    int g_mean_result = -1;
                    //    int b_mean_result = -1;
                    //    Logger.Info($"============阈值范围============：{model.AllowRange}");
                    //    bol = _client.GetPropose(model.TestR, model.TestG, model.TestB,
                    //                             model.AllowRange,
                    //                             ref r_mean_result, ref g_mean_result, ref b_mean_result,
                    //                             ref flag);
                    //    if (bol == false)
                    //        return "计算RGB值错误";
                    //    else
                    //    {
                    //        model.MultiplyR = r_mean_result;
                    //        model.MultiplyG = g_mean_result;
                    //        model.MultiplyB = b_mean_result;
                    //    }
                    //}

                    //Logger.Info($"============当前类型============：{model.Type}，校准结果：{flag}");
                    //CalibrationEnum tempType = model.LastCalibrationType;
                    //model.LastCalibrationType = model.Type;
                    //if (flag == 2)
                    //{
                    //    model.IsComplete = true;
                    //    if (tempType != CalibrationEnum.Light && model.Type == CalibrationEnum.Light)
                    //    {
                    //        model.LastCalibrationType = tempType;
                    //    }
                    //    //如果不是光源校准，且不是从相机校准到光源，那么下一次校准为精调
                    //    if (_isLight == true && model.IsCameraToLight == false)
                    //        model.Type = CalibrationEnum.Minutely;
                    //    else
                    //        model.Type = CalibrationEnum.Light;
                    //}
                    //else
                    //{
                    //    model.IsComplete = false;
                    //    if (_isLight == false)
                    //    {
                    //        //如果不是调光源，那么当flag为0的时候代表粗调相机
                    //        if (flag == 0)
                    //            model.Type = CalibrationEnum.Rough;
                    //        //1代表要精调相机
                    //        else if (1 == flag)
                    //            model.Type = CalibrationEnum.Minutely;
                    //    }
                    //    else
                    //        model.Type = CalibrationEnum.Light;

                    //}
                    #endregion

                    return null;
                }
                catch (Exception ex)
                {
                    Logger.Error("校准分析过程异常：", ex);
                    return string.Empty;
                }
            });
        }

        public Bitmap AddCenterMark(string fileName, string targetFile)
        {
            try
            {
                Bitmap bitmap = new Bitmap(fileName);
                BitmapData bitmapdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                int newWidth = 0, newHeight = 0, newStep = 0;
                IntPtr targetImage = _client.Add_center_mark(bitmapdata.Width, bitmapdata.Height, 3, bitmapdata.Scan0, bitmapdata.Stride, 0, 0, ref newWidth, ref newHeight, ref newStep, 5);
                using (Bitmap result = new Bitmap(newWidth, newHeight, newStep, bitmapdata.PixelFormat, targetImage))
                {
                    result.Save(targetFile, ImageFormat.Png);
                }

                bitmap.UnlockBits(bitmapdata);
                bitmap.Dispose();
                FreeImage(targetImage);
                return new Bitmap(targetFile);
            }
            catch (Exception ex)
            {
                Logger.Error("添加中心点异常：", ex);
                return null;
            }
        }

        public bool SetRol(int x, int y, int w, int h)
        {
            return _client.SetRol(x, y, w, h);
        }

        public bool FreeImage(IntPtr image)
        {
            try
            {
                return _client.FreeImage(image);
            }
            catch (Exception ex)
            {
                Logger.Error("释放中心点图片资源失败：", ex);
                return false;
            }
        }

        public string GetVersion()
        {
            return _client.GetVersion();
        }

        public bool SaveStandHuibanImg(CalibrationCfgModel cfg, CalibrationSDKModel model)
        {
            if (cfg == null || model == null)
                return false;

            IntPtr dir = Marshal.StringToHGlobalAnsi(model.ImageDir);
            var bol = _client.SaveStandHuibanImg(dir, cfg.X, cfg.Y, cfg.Width, cfg.Height, model.ImageCount, cfg.RemoveRate, 1);
            return bol;
        }
    }
}
